#if !defined(RANDOMSCENE_H)
#define RANDOMSCENE_H

#include "Sphere.hpp"
#include "ObjectList.hpp"

#include "Lambertian.hpp"
#include "Dielectric.hpp"
#include "Metal.hpp"


ObjectList rand_scene() {
    ObjectList world;
    auto groundMat = std::make_shared<Lambertian>(Eigen::Vector3f(0.5, 0.5, 0.6));
    world.add(std::make_shared<Sphere>(
        Eigen::Vector3f(0, -1000, 0),
        1000,
        groundMat
        ));
    for (int a = -11; a < 11; a++) {
        for (int b = -11; b < 11; b++) {
            float choose_mat = rand_float();
            Eigen::Vector3f center(a + 0.9 * rand_float(), 0.2, b + 0.9 * rand_float());
            if ((center - Eigen::Vector3f(4, 0.2, 0)).norm() > 0.9) {
                std::shared_ptr<Material> sphere_material;
                if (choose_mat < 0.8) {
                    // diffuse
                    Eigen::Vector3f albedo = rand_vec(0, 1);
                    sphere_material = std::make_shared<Lambertian>(albedo);
                    world.add(std::make_shared<Sphere>(center, 0.2,
                        sphere_material));
                }
                else if (choose_mat < 0.95) {
                    // metal
                    Eigen::Vector3f albedo = rand_vec(0.5, 1);
                    float fuzz = rand_float(0, 0.5);
                    sphere_material = std::make_shared<Metal>(albedo, fuzz);
                    world.add(std::make_shared<Sphere>(center, 0.2,
                        sphere_material));
                }
                else {
                    // glass
                    sphere_material = std::make_shared<Dielectric>(1.5, Eigen::Vector3f(1,1,1));
                    world.add(std::make_shared<Sphere>(center, 0.2,
                        sphere_material));
                }
            }
        }
    }
    auto material1 = std::make_shared<Dielectric>(1.5, Eigen::Vector3f(1,1,1));
    world.add(std::make_shared<Sphere>(Eigen::Vector3f(0, 1, 0), 1.0, material1));
    auto material2 = std::make_shared<Lambertian>(Eigen::Vector3f(0.4, 0.2, 0.1));
    world.add(std::make_shared<Sphere>(Eigen::Vector3f(-4, 1, 0), 1.0, material2));
    auto material3 = std::make_shared<Metal>(Eigen::Vector3f(0.7, 0.6, 0.5), 0.0);
    world.add(std::make_shared<Sphere>(Eigen::Vector3f(4, 1, 0), 1.0, material3));
    return world;
}

#endif // RANDOMSCENE_H
